package instances

import (
	"errors"
	"fmt"
	"gluenet/pkg/apis"
	"gluenet/pkg/gerrors"
	"gluenet/pkg/meta"
)

func GetInstance(ctx *apis.GlueContext) {
	var (
		err error
		key string
		//kind string
		mode string
	)
	key = ctx.WebContext.URLParam("guid")
	//kind = ctx.WebContext.URLParam("kind")
	mode = ctx.WebContext.URLParam("mode")
	ctx.Logger.Debugf("get config Label: %v", key)

	//查询数据库
	var ins *meta.Instance
	if err = ctx.DataBase.InstanceGet(key, &ins); err != nil {
		if errors.Is(err, gerrors.DataNotFind) {
			ctx.WebContext.JSON(apis.ResponseOK(nil))
			return
		}
		ctx.Logger.Errorf("query error:%v, or data is nil", err)
		ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("query error:%v, or data is nil", err), nil))
		return
	}
	//var ins []meta.Instance
	//if err = orm2.InstanceGet(ctx.DataBase, key, &ins); err != nil {
	//	ctx.Logger.Errorf("query error:%v, or data is nil", err)
	//	ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("query error:%v, or data is nil", err), nil))
	//	return
	//}
	//if len(ins) == 0 {
	//	ctx.WebContext.JSON(apis.ResponseOK(nil))
	//	return
	//}
	var state *meta.InstanceStatus
	if err = ctx.DataBase.InstanceStatusGet(key, &state); err != nil {
		ctx.Logger.Errorf("get instance runtime error:%v, or data is nil", err)
		ctx.WebContext.JSON(apis.ResponseInterErr(fmt.Errorf("get instance runtime error:%v, or data is nil", err), nil))
		return
	}

	//返回结果解码，根据不同的应用
	in, _, err := apis.DecodeInstanceValue(ins.InstanceValue, mode)
	if err != nil {
		ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("unmarshall instance %v", err), nil))
		ctx.Logger.Errorf("unmarshall instance %v", err)
		return
	}

	n, _ := ctx.WebContext.JSON(apis.ResponseOK(map[string]interface{}{
		"label":      ins.Label,
		"guid":       ins.Guid,
		"name":       ins.Name,
		"state":      state.State,
		"containers": state.Contaienrs,
		"value":      in,
	}))
	ctx.Logger.Debugf("get instance response bytes: %v", n)
}

func ListInstances(ctx *apis.GlueContext) {
	var (
		err error
		//kind string
		//mode = apis.ModuleDefault
	)

	//kind = ctx.WebContext.URLParam("kind")
	//mode = ctx.WebContext.URLParam("mode")

	//查询数据库
	var ins []meta.Instance
	if err = ctx.DataBase.InstanceListAll(&ins); err != nil {
		//if err = ctx.DataBase.InstanceList(mode, kind, &ins); err != nil {
		ctx.Logger.Errorf("query error:%v, or data is nil", err)
		ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("query error:%v, or data is nil", err), nil))
		return
	}

	if len(ins) == 0 {
		ctx.WebContext.JSON(apis.ResponseOK(nil))
		return
	}

	//返回结果
	in := make([]map[string]interface{}, len(ins))
	for k, v := range ins {
		in[k] = make(map[string]interface{})
		in[k]["label"] = v.Label
		in[k]["guid"] = v.Guid
		in[k]["name"] = v.Name
		in[k]["platform"] = v.Platform
		//in[k]["value"], err = apis.DecodeInstanceValue(v.InstanceValue, mode)
		in[k]["value"], in[k]["kind"], err = apis.DecodeInstanceValue(v.InstanceValue, v.Platform)
		if err != nil {
			ctx.Logger.Errorf("unmarshall config %v", err)
			ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("unmarshall config %v", err), nil))
			return
		}

		var state *meta.InstanceStatus
		if err = ctx.DataBase.InstanceStatusGet(v.Guid, &state); err != nil {
			ctx.Logger.Errorf("get instance runtime error:%v, or data is nil", err)
			ctx.WebContext.JSON(apis.ResponseInterErr(fmt.Errorf("get instance runtime error:%v, or data is nil", err), nil))
			return
		}

		in[k]["state"] = state.State
		in[k]["containers"] = state.Contaienrs
	}

	n, _ := ctx.WebContext.JSON(apis.ResponseOK(in))
	ctx.Logger.Debugf("list instance all response bytes: %v", n)
}

func ListInstancesKind(ctx *apis.GlueContext) {
	var (
		err error
		ins []meta.Instance
	)
	kind := ctx.WebContext.URLParam("kind")

	if err = ctx.DataBase.InstanceKindList(kind, &ins); err != nil {
		ctx.Logger.Errorf("query error:%v, or data is nil", err)
		ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("query error:%v, or data is nil", err), nil))
		return
	}

	if len(ins) == 0 {
		ctx.WebContext.JSON(apis.ResponseOK(nil))
		return
	}

	//返回结果
	in := make([]map[string]interface{}, len(ins))
	for k, v := range ins {
		in[k] = make(map[string]interface{})
		in[k]["label"] = v.Label
		in[k]["guid"] = v.Guid
		in[k]["name"] = v.Name
		in[k]["platform"] = v.Platform
		in[k]["value"], in[k]["kind"], err = apis.DecodeInstanceValue(v.InstanceValue, v.Platform)
		if err != nil {
			ctx.Logger.Errorf("unmarshall config %v", err)
			ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("unmarshall config %v", err), nil))
			return
		}

		if version, describe, err := apis.GetVersionAndDescribeFromInstance(&v); err == nil {
			in[k]["version"] = version
			in[k]["describe"] = describe
		} else {
			in[k]["version"] = ""
			in[k]["describe"] = ""
		}

		var state *meta.InstanceStatus
		if err = ctx.DataBase.InstanceStatusGet(v.Guid, &state); err != nil {
			ctx.Logger.Errorf("get instance runtime error:%v, or data is nil", err)
			ctx.WebContext.JSON(apis.ResponseInterErr(fmt.Errorf("get instance runtime error:%v, or data is nil", err), nil))
			return
		}

		in[k]["state"] = state.State
		in[k]["containers"] = state.Contaienrs
	}

	n, _ := ctx.WebContext.JSON(apis.ResponseOK(in))
	ctx.Logger.Debugf("list instances response bytes: %v", n)
}

func ListInstancesTotal(ctx *apis.GlueContext) {
	var (
		err error
		ins []meta.Instance
	)
	if err = ctx.DataBase.InstanceListAll(&ins); err != nil {
		ctx.Logger.Errorf("query error:%v, or data is nil", err)
		ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("query error:%v, or data is nil", err), nil))
		return
	}

	if len(ins) == 0 {
		ctx.WebContext.JSON(apis.ResponseOK(nil))
		return
	}

	//返回结果
	in := make([]map[string]interface{}, len(ins))
	for k, v := range ins {
		in[k] = make(map[string]interface{})
		in[k]["label"] = v.Label
		in[k]["guid"] = v.Guid
		in[k]["name"] = v.Name
		in[k]["platform"] = v.Platform
		in[k]["value"], in[k]["kind"], err = apis.DecodeInstanceValue(v.InstanceValue, v.Platform)
		if err != nil {
			ctx.Logger.Errorf("unmarshall config %v", err)
			ctx.WebContext.JSON(apis.ResponseReqErr(fmt.Errorf("unmarshall config %v", err), nil))
			return
		}

		if version, describe, err := apis.GetVersionAndDescribeFromInstance(&v); err == nil {
			in[k]["version"] = version
			in[k]["describe"] = describe
		} else {
			in[k]["version"] = ""
			in[k]["describe"] = ""
		}

		var state *meta.InstanceStatus
		if err = ctx.DataBase.InstanceStatusGet(v.Guid, &state); err != nil {
			ctx.Logger.Errorf("get instance runtime error:%v, or data is nil", err)
			ctx.WebContext.JSON(apis.ResponseInterErr(fmt.Errorf("get instance runtime error:%v, or data is nil", err), nil))
			return
		}

		in[k]["state"] = state.State
		in[k]["containers"] = state.Contaienrs
	}

	n, _ := ctx.WebContext.JSON(apis.ResponseOK(in))
	ctx.Logger.Debugf("list instances response bytes: %v", n)
}
